<!DOCTYPE html>
<html lang="UTF-8">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传</title>
    <script src="./spark-md5.js"></script> <!-- 引入 SparkMD5 库 -->
</head>
<body>
    <input type="file" /> <!-- 文件输入框 -->
    <script>
        const inp = document.querySelector('input'); // 获取文件输入元素
        inp.onchange = async (e) => {
            const file = inp.files[0]; // 获取选择的文件
            if (!file) {
                return; // 如果没有选择文件，退出函数
            }
    
            const largeChunks = createChunks(file, 500 * 1024 * 1024); // 按500MB分片
            const promises = largeChunks.map(async (largeChunk) => {
                const smallChunks = createChunks(largeChunk, 10 * 1024 * 1024); // 在每个大分片内按10MB分片
                const md5 = await hash(smallChunks); // 计算每个大分片的 MD5 值
                return md5;
            });
    
            const md5s = await Promise.all(promises); // 并行计算所有大分片的 MD5 值
            console.log(md5s); // 打印所有大分片的 MD5 值
            
            // 计算最终的 MD5 值
            const finalMd5 = hashFinalMd5(md5s);
            console.log('Final MD5:', finalMd5);
        };
    
        function hash(chunks) {
            const spark = new SparkMD5(); // 创建 SparkMD5 实例
    
            return new Promise((resolve) => {
                function _read(i) {
                    if (i >= chunks.length) {
                        resolve(spark.end()); // 所有分片读取完毕，返回 MD5 值
                        return;
                    }
                    const blob = chunks[i];
                    const reader = new FileReader(); // 创建 FileReader 实例
                    reader.onload = (e) => {
                        const bytes = e.target.result;
                        spark.append(bytes); // 将分片内容添加到 SparkMD5 实例中
                        _read(i + 1); // 读取下一个分片
                    };
                    reader.readAsArrayBuffer(blob); // 读取分片内容为 ArrayBuffer
                }
    
                _read(0); // 从第一个分片开始读取
            });
        }
        
        function hashFinalMd5(md5s) {
            const spark = new SparkMD5(); // 创建 SparkMD5 实例
            md5s.forEach(md5 => spark.append(md5)); // 将所有 MD5 值添加到 SparkMD5 实例中
            return spark.end(); // 返回最终的 MD5 值
        }
    
        function createChunks(file, chunkSize) {
            const chunks = [];
            let offset = 0;
            while (offset < file.size) {
                const chunk = file.slice(offset, offset + chunkSize); // 按指定大小分片
                chunks.push(chunk);
                offset += chunkSize; // 更新偏移量
            }
            return chunks; // 返回分片数组
        }
    </script>
</body>
</html>
